#include <stdio.h>
#include <stdlib.h>
#include "dlist.h"


// frist static function to create a new node
// only use in this file
static dNode_t *__newNode(int x) {
    dNode_t *node = (dNode_t *)malloc(sizeof(dNode_t));
    if (node != NULL) {
        node->data = x;
        node->next = NULL;
        node->prev = NULL;
    }
    return node;
}

//insert new_node after node
static void __insertNode(dNode_t *node, dNode_t *new_node) {
    new_node->next = node->next;
    node->next->prev = new_node;
    new_node->prev = node;
    node->next = new_node; 
}

//insert x after prevNode
void insertAfter(dNode_t *prevNode, int x) {
    dNode_t *node = __newNode(x);
    if (!node) return;
    if (prevNode == NULL) {
        prevNode = node;
        node->next = prevNode;
        node->prev = prevNode;
    } else {
        __insertNode(prevNode, node);
    }
}

//insert x at front
void insertAtFront(dNode_t **head, int x) {
    dNode_t *node = __newNode(x);
    if (!node) return;

    if ( !*head ) { //head==NULL
        *head = node;
        node->next = node;
        node->prev = node;
    } else {
        __insertNode((*head)->prev, node);
        *head = node;
    }
} 


//insert node at tail
void insertAtTail(dNode_t **head, int x) {
    dNode_t *node = __newNode(x);
    if ( !*head ) { //head==NULL
        *head = node;
        node->next = node;
        node->prev = node;
    } else {
        __insertNode((*head)->prev,node);
    }
}

//delete a node from front
dNode_t * deleteFromFront(dNode_t **head){
    if (!*head) return NULL;

    dNode_t *frontNode = *head;
    if (frontNode->next == *head) //only one node in list
        *head = NULL;
    else  {
        *head = (*head)->next;
        frontNode->prev->next = *head;
        (*head)->prev = frontNode->prev;
    }    
    return frontNode;
}

void printList(dNode_t *head) {
    dNode_t *ptrNode = head;

    if (!head) {
        printf("list is empty\n");
        return;
    }
    while(ptrNode->next != head) {
        //printf("%p next=%p, prev=%p %d \n", ptrNode,ptrNode->next,ptrNode->prev,ptrNode->data);
        printf("%d ", ptrNode->data);
        ptrNode = ptrNode->next;
    }
    printf("%d\n", ptrNode->data);
    //printf("%p next=%p, prev=%p %d \n", ptrNode,ptrNode->next,ptrNode->prev,ptrNode->data);
}


void reversePrintList(dNode_t *head) {
    dNode_t *ptrNode = head->prev;

    if (!head) {
        printf("list is empty\n");
        return;
    }
    while(ptrNode != head) {
        printf("%d ", ptrNode->data);
        ptrNode = ptrNode->prev;
    }
    printf("%d\n", ptrNode->data);
}
